﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace ttlang.node
{
    //代码节点，函数内的部分
    public interface Node_CodeAtom : Node
    {
    }

    public class Node_CodeBlock : Node_CodeAtom
    {
        public srcinfo srcinfo
        {
            get;
            set;
        }
        public NodeType type => NodeType.CODE_BLOCK;

        public List<Node_CodeAtom> items = new List<Node_CodeAtom>();
        public void Dump(int deep)
        {
            string space = "";
            for (var i = 0; i < deep; i++)
                space += "    ";

            Console.WriteLine(space + "NodeBlock{");
            foreach (var t in items)
            {
                t.Dump(deep + 1);
            }
            Console.WriteLine(space + "}");
        }
    }
    public enum CommentType
    {
        SINGLELINE,
        RANGE,
    }
    public class Node_Code_Comment : Node_CodeAtom
    {
        public CommentType commonttype;
        public string comment = "";

        public srcinfo srcinfo
        {
            get;
            set;
        }
        public NodeType type => NodeType.CODE_COMMENT;
        public void Dump(int deep)
        {
            string space = "";
            for (var i = 0; i < deep; i++)
                space += "    ";

            Console.WriteLine(space + "COMMENT type:" + type + ":" + comment);
        }
    }
    //like var i
    //     var i = 0
    //     var i:int32 = 0
    public class Node_Code_ValueDef : Node_CodeAtom
    {
        public string id = "";
        public semantic.TTType deftype;
        public Node_Expr initvlaue;

        public srcinfo srcinfo
        {
            get;
            set;
        }
        public NodeType type => NodeType.CODE_VALUEDEF;
        public void Dump(int deep)
        {
            string space = "";
            for (var i = 0; i < deep; i++)
                space += "    ";

            Console.WriteLine(space + "Node_Code_ValueDef:" + id + ":" + deftype?.name);
            initvlaue?.Dump(deep + 1);
        }
    }

    //like i=1
    public class Node_Code_Set:Node_CodeAtom
    {
        public string id = "";
        
        public Node_Expr initvlaue;

        public srcinfo srcinfo
        {
            get;
            set;
        }
        public NodeType type => NodeType.CODE_SET;
        public void Dump(int deep)
        {
            string space = "";
            for (var i = 0; i < deep; i++)
                space += "    ";

            Console.WriteLine(space + "Node_Code_Set:" + id + "=" + initvlaue.tttype);
            initvlaue?.Dump(deep + 1);
        }
    }

    //like i++
    public class Node_Code_SelfOf : Node_CodeAtom
    {
        public Node_Expr id_expr;//格局開了
        public string token = "";
        public Node_Expr rightvalue;
        public srcinfo srcinfo
        {
            get;
            set;
        }
        public NodeType type => NodeType.CODE_SELFOP;
        public void Dump(int deep)
        {
            string space = "";
            for (var i = 0; i < deep; i++)
                space += "    ";
            Console.WriteLine(space + "Node_Code_SelfOf:" + token);
            id_expr.Dump(deep + 1);
            if (rightvalue != null)
            {
                Console.WriteLine(space + "    " + token);
                rightvalue.Dump(deep + 1);
            }
        }
    }

    public class Node_Code_If : Node_CodeAtom
    {
        //if
        public Node_Expr elem_cond;
        //主體
        public Node_CodeAtom body;

        public Node_CodeAtom elsepart;
        public srcinfo srcinfo
        {
            get;
            set;
        }
        public NodeType type => NodeType.CODE_IF;
        public void Dump(int deep)
        {
            string space = "";
            for (var i = 0; i < deep; i++)
                space += "    ";
            Console.WriteLine(space + "Node_Code_For:");
            elem_cond.Dump(deep + 1);
            body.Dump(deep + 1);
            if(elsepart!=null)
            {
                elsepart.Dump(deep + 1);
            }
        }
    }
    public class Node_Code_For : Node_CodeAtom
    {
        //for 三段
        public Node_CodeAtom elem_init;
        public Node_Expr elem_cond;
        public Node_CodeAtom elem_step;
        //主體
        public Node_CodeAtom body;
        public srcinfo srcinfo
        {
            get;
            set;
        }
        public NodeType type => NodeType.CODE_FOR;
        public void Dump(int deep)
        {
            string space = "";
            for (var i = 0; i < deep; i++)
                space += "    ";
            Console.WriteLine(space + "Node_Code_For:");
            elem_init.Dump(deep + 1);
            elem_cond.Dump(deep + 1);
            elem_step.Dump(deep + 1);
            body.Dump(deep + 1);
        }
    }
    public class Node_Code_Call : Node_CodeAtom
    {
        public Node_Expr_Call call_expr;
        public srcinfo srcinfo
        {
            get;
            set;
        }
        public NodeType type => NodeType.CODE_CALL;
        public void Dump(int deep)
        {
            string space = "";
            for (var i = 0; i < deep; i++)
                space += "    ";
            Console.WriteLine(space + "Node_Expr_Call:");
            call_expr.Dump(deep + 1);
        }
    }

    public class Node_Code_Return : Node_CodeAtom
    {
        public Node_Expr vlaue;
        public srcinfo srcinfo
        {
            get;
            set;
        }
        public NodeType type => NodeType.CODE_RETURN;
        public void Dump(int deep)
        {
            string space = "";
            for (var i = 0; i < deep; i++)
                space += "    ";

            Console.WriteLine(space + "Node_Code_Return:");
            vlaue?.Dump(deep + 1);
        }
    }

}
